package com.manager.commons.mybatis.service;

import java.util.*;


import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;

import com.manager.commons.log.LogFactory;
import com.manager.commons.utils.DateUtil;
import com.manager.commons.utils.StringUtil;
import com.manager.commons.utils.UUIDUtil;
import com.manager.commons.base.DataGrid;
import com.manager.commons.mybatis.dao.GenericDao;
import com.manager.core.web.json.AjaxJson;
/**
 * 自定义Service 事物传播行为介绍:
 *
 * @author H
 * @Transactional(propagation=Propagation.REQUIRED) 如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
 * @Transactional(propagation=Propagation.NOT_SUPPORTED) 容器不为这个方法开启事务
 * @Transactional(propagation=Propagation.REQUIRES_NEW) 不管是否存在事务, 都创建一个新的事务, 原来的挂起, 新的执行完毕, 继续执行老的事务
 * @Transactional(propagation=Propagation.MANDATORY) 必须在一个已有的事务中执行, 否则抛出异常
 * @Transactional(propagation=Propagation.NEVER) 必须在一个没有的事务中执行, 否则抛出异常(与Propagation.MANDATORY相反)
 * @Transactional(propagation=Propagation.SUPPORTS) 如果其他bean调用这个方法, 在其他bean中声明事务, 那就用事务;如果其他bean没有声明事务,那就不用事务
 * @Transactional(timeout=30) 事物超时设置：默认是30秒事务隔离级别（MYSQL：默认为REPEATABLE_READ；级别SQLSERVER：默认为READ_COMMITTED）
 * @Transactional(isolation=Isolation.READ_UNCOMMITTED) 读取未提交数据(会出现脏读, 不可重复读)基本不使用
 * @Transactional(isolation = Isolation.READ_COMMITTED) 读取已提交数据(会出现不可重复读和幻读)
 * @Transactional(isolation = Isolation.REPEATABLE_READ) 可重复读(会出现幻读)
 * @Transactional(isolation = Isolation.SERIALIZABLE) 串行化只读
 * @Transactional(readOnly=true) 事务回滚
 * @Transactional(rollbackFor=RuntimeException.class)
 * @Transactional(rollbackFor={RuntimeException.class, Exception.class})
 * @Transactional(rollbackForClassName="RuntimeException")
 * @Transactional(rollbackForClassName={"RuntimeException","Exception") 事务不回滚
 * @Transactional(noRollbackFor=RuntimeException.class)
 * @Transactional(noRollbackFor={RuntimeException.class, Exception.class})
 * @Transactional(noRollbackForClassName="RuntimeException")
 * @Transactional(noRollbackForClassName={"RuntimeException","Exception")
 */
public abstract class GenericService<Model> {

    protected Logger logger = LogFactory.getLogger(this.getClass());

    /**
     * 定义成抽象方法,由子类实现,完成dao的注入
     *
     * @return GenericDao实现类
     */
    public abstract GenericDao<Model> getDao();

    /**
     * 插入
     *
     * @param model
     * @return
     */
    public int insert(Model model) {
        return getDao().insert(model);
    }

    /**
     * 插入
     *
     * @param params
     * @return
     */
    public int insertMap(Map<?, ?> params) {
        return getDao().insertMap(params);
    }

    /**
     * 更新
     *
     * @param model
     * @return
     */
    public int update(Model model) {
        return getDao().update(model);
    }

    /**
     * 更新
     *
     * @param params
     * @return
     */
    public int updateMap(Map<?, ?> params) {
        return getDao().updateMap(params);
    }

    /**
     * 删除
     *
     * @param params
     * @return
     */
    public int deleteMap(Map<?, ?> params) {
        return getDao().deleteMap(params);
    }

    /**
     * 销毁
     *
     * @param params
     * @return
     */
    public int destroyMap(Map<?, ?> params) {
        return getDao().destroyMap(params);
    }

    /**
     * 更新或插入
     *
     * @param model
     * @return
     */
    public int upsert(Model model) {
        return getDao().upsert(model);
    }

    /**
     * 更新或插入
     *
     * @param params
     * @return
     */
    public int upsertMap(Map<?, ?> params) {
        return getDao().upsertMap(params);
    }

    /**
     * 状态
     *
     * @param params
     * @return
     */
    public int statusMap(Map<?, ?> params) {
        return getDao().statusMap(params);
    }

    /**
     * 根据主键ID查询
     *
     * @param _id
     * @return
     */
    public Model findById(String _id) {
        return getDao().findMap(new HashMap<String, Object>() {
            {
                put("_id", _id);
            }
        });
    }

    /**
     * 查询
     *
     * @param params
     * @return
     */
    public Model findMap(Map<?, ?> params) {
        return getDao().findMap(params);
    }

    /**
     * 查询（根据某个字段）
     *
     * @param column
     * @param val
     * @return
     */
    public Model find(String column, Object val) {
        return findMap(new HashMap<String, Object>() {
            {
                put(column, val);
            }
        });
    }

    /**
     * 统计
     *
     * @param params
     * @return
     */
    public int countMap(Map<?, ?> params) {
        return getDao().countMap(params);
    }

    /**
     * 查询列表
     *
     * @param params
     * @return
     */
    public List<Model> queryMap(Map<?, ?> params) {
        return getDao().queryMap(params);
    }

    /**
     * 查询列表（根据某个字段）
     *
     * @param column
     * @param val
     * @return
     */
    public List<Model> query(String column, Object val) {
        return queryMap(new HashMap<String, Object>() {
            private static final long serialVersionUID = -6222987418571435571L;

            {
                put(column, val);
            }
        });
    }
    public Model    findModel(String id){
        return getDao().findModel(id);
    }
    /**
     * 分页查询
     *
     * @param params
     * @return
     */
    public DataGrid queryPage(Map<String, Object> params) {
        try {
            if (null != params) {
                int count = getDao().countMap(params);
                List<Model> list = getDao().queryMap(params);
                return new DataGrid(count, list);
            }

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return new DataGrid(0, new ArrayList<Model>());
    }

    /**
     * 新增
     *
     * @param params
     * @return
     */
    public AjaxJson add(Map<String, Object> params) {
        try {
            if (null != params) {
                String _id = String.valueOf(params.get("_id"));
                if (StringUtil.isEmpty(_id)) {
                    String uuid = UUIDUtil.getInstance().getUUID();
                    params.put("_id", uuid);
                }
                int f = insertMap(params);
                return new AjaxJson(f, "提交".concat(f > 0 ? "成功" : "失败"));
            }
            return new AjaxJson("参数错误");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return new AjaxJson("异常错误，请稍后再试");
    }

    /**
     * 保存
     *
     * @param params
     * @param index
     * @return
     */
    public AjaxJson save(Map<String, Object> params, int index) {
        try {
            if (null != params) {
                String _id = String.valueOf(params.get("_id"));
                int f = 0;
                if (StringUtil.isEmpty(_id)) {
                    String uuid = UUIDUtil.getInstance().getUUID();
                    if (index > 0) {
                        uuid = UUIDUtil.getInstance().getUUIDDate(index);
                    }
                    params.put("_id", uuid);
                    params.put("id", uuid);
                    f = insertMap(params);
                } else {
                    params.put("id", _id);
                    f = updateMap(params);
                }
                return new AjaxJson(f, "保存".concat(f > 0 ? "成功" : "失败"));
            }
            return new AjaxJson("参数错误");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return new AjaxJson("异常错误，请稍后再试");
    }

    /**
     * 保存
     *
     * @param params
     * @return
     */
    public AjaxJson save(Map<String, Object> params) {
        return save(params, 0);
    }
    /**
     * 删除
     *
     * @param params
     * @return
     */
    public AjaxJson delete(Map<String, Object> params) {
        try {
            if (null != params) {
                int f = deleteMap(params);
                return new AjaxJson(f, "操作".concat(f > 0 ? "成功" : "失败"));
            }
            return new AjaxJson("参数错误");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return new AjaxJson("异常错误，请稍后再试");
    }

    /**
     * 销毁
     *
     * @param params
     * @return
     */
    public AjaxJson destroy(Map<String, Object> params) {
        try {
            if (null != params) {
                int f = destroyMap(params);
                return new AjaxJson(f, "操作".concat(f > 0 ? "成功" : "失败"));
            }
            return new AjaxJson("参数错误");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return new AjaxJson("异常错误，请稍后再试");
    }

    /**
     * 改变状态
     *
     * @param params
     * @return
     */
    public AjaxJson status(Map<String, Object> params) {
        try {
            if (null != params) {
                params.put("createTime", DateUtil.currentDateTime());
                int f = statusMap(params);
                return new AjaxJson(f, "操作".concat(f > 0 ? "成功" : "失败"));
            }
            return new AjaxJson("参数错误！");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return new AjaxJson("异常错误，请稍后再试！");
    }



    /**
     * 查询json格式数据
     *
     * @param params
     * @return
     */
    public String querySelect(List<Map<String, String>> result, Map<String, Object> params) {
        if (params != null) {
            // s代表为搜索条件需要显示请选择
            boolean s = params.containsKey("s");
            if (result != null && s) {
                result.add(0, new HashMap<String, String>() {
                    {
                        put("text", "---请选择---");
                        put("value", null);
                    }
                });
            }
        }
        return JSON.toJSONString(result);
    }
    /**
     * 查询json格式数据
     *
     * @param params
     * @return
     */
    public void queryCodeSelect(List<Map<String, String>> result, Map<String, Object> params) {
        if (params != null) {
            // s代表为搜索条件需要显示请选择
            boolean s = params.containsKey("a");
            if (result != null && s) {
                result.add(0, new HashMap<String, String>() {
                    {
                        put("code", "");
                        put("codeName", "全部");
                    }
                });
            }
        }
    }
    /**
     * 获取参数如果为null则返回空字符串
     *
     * @param params
     * @param key
     * @return
     */
    public String getParamsString(Map<String, Object> params, String key) {
        if (params.containsKey(key)) {
            Object value = params.get(key);
            if (value != null) {
                return String.valueOf(value);
            }
            return "";
        } else {
            return "";
        }
    }

    /**
     * 获取参数如果为null则返回空字符串
     *
     * @param params
     * @param key
     * @return
     */
    public int getParamsInt(Map<String, Object> params, String key) {
        if (params.containsKey(key)) {
            Object value = params.get(key);
            if (value != null) {
                try {
                    return Integer.parseInt(String.valueOf(value));
                } catch (Exception e) {
                    return 0;
                }

            }
            return 0;
        } else {
            return 0;
        }
    }



    protected String check(Map<String, Object> params, Map<String, String> required) {
        Set<String> keySet = required.keySet();
        for (String key : keySet) {
            if (params.containsKey(key)) {
                String value = String.valueOf(params.get(key));
                if (StringUtil.isEmpty(value)) {
                    return required.get(key);
                }
            }
        }
        return "";
    }

    public String getCreator(Map<String, Object> params) {
        return getParamsString(params, "creator");
    }
    public Model getModel() {
        return null;
    }
}